﻿using System;
using System.Collections.Generic;
using System.Text;

namespace AJAXChatClient
{
    public class AjaxChatSettings
    {
        private bool bbCode = true;
        private bool bbCodeImages = true;
        private bool bbCodeColors = true;
        private bool hyperLinks = true;
        private bool lineBreaks = true;
        private bool emoticons = true;
        private bool autoFocus = true;
        private bool autoScroll = true;
        private int maxMessages = 0;
        private bool wordWrap = true;
        private int maxWordLength = 32;
        private string dateFormat = "(%H:%i:%s)";
        private bool persistFontColor = false;
        private string fontColor = null;
        private bool audio = true;
        private float audioVolume = 1.0f;
        private string soundReceive = "sound_1";
        private string soundSend = "sound_2";
        private string soundEnter = "sound_3";
        private string soundLeave = "sound_4";
        private string soundChatBot = "sound_5";
        private string soundError = "sound_6";
        private bool blink = true;
        private int blinkInterval = 500;
        private int blinkIntervalNumber = 10;

        private string ignoredUserNames = "";

        /// <summary>
        /// Defines if BBCode tags are replaced with the associated HTML code tags.
        /// </summary>
        public bool BBCode
        {
            get { return this.bbCode; }
            set
            {
                if (this.bbCode != value)
                {
                    this.bbCode = value;
                }
            }
        }

        /// <summary>
        /// Defines if image BBCode is replaced with the associated image HTML code.
        /// </summary>
        public bool BBCodeImages
        {
            get { return this.bbCodeImages; }
            set
            {
                if (this.bbCodeImages != value)
                {
                    this.bbCodeImages = value;
                }
            }
        }

        /// <summary>
        /// Defines if color BBCode is replaced with the associated color HTML code.
        /// </summary>
        public bool BBCodeColors
        {
            get { return this.bbCodeColors; }
            set
            {
                if (this.bbCodeColors != value)
                {
                    this.bbCodeColors = value;
                }
            }
        }

        /// <summary>
        /// Defines if hyperlinks are made clickable.
        /// </summary>
        public bool HyperLinks
        {
            get { return this.hyperLinks; }
            set
            {
                if (this.hyperLinks != value)
                {
                    this.hyperLinks = value;
                }
            }
        }

        /// <summary>
        /// Defines if line breaks are enabled.
        /// </summary>
        public bool LineBreaks
        {
            get { return this.lineBreaks; }
            set
            {
                if (this.lineBreaks != value)
                {
                    this.lineBreaks = value;
                }
            }
        }

        /// <summary>
        /// Defines if emoticon codes are replaced with their associated images.
        /// </summary>
        public bool Emoticons
        {
            get { return this.emoticons; }
            set
            {
                if (this.emoticons != value)
                {
                    this.emoticons = value;
                }
            }
        }

        /// <summary>
        /// Defines if the focus is automatically set to the input field on chat load or channel switch.
        /// </summary>
        public bool AutoFocus
        {
            get { return this.autoFocus; }
            set
            {
                if (this.autoFocus != value)
                {
                    this.autoFocus = value;
                }
            }
        }

        /// <summary>
        /// Defines if the chat list scrolls automatically to display the latest messages.
        /// </summary>
        public bool AutoScroll
        {
            get { return this.autoScroll; }
            set
            {
                if (this.autoScroll != value)
                {
                    this.autoScroll = value;
                }
            }
        }

        /// <summary>
        /// The maximum count of messages displayed in the chat list (will be ignored if &lt;= 0).
        /// </summary>
        public int MaxMessages
        {
            get { return this.maxMessages; }
            set
            {
                if (this.maxMessages != value)
                {
                    this.maxMessages = value;
                }
            }
        }

        /// <summary>
        /// Defines if long words are wrapped to avoid vertical scrolling.
        /// </summary>
        public bool WordWrap
        {
            get { return this.wordWrap; }
            set
            {
                if (this.wordWrap != value)
                {
                    this.wordWrap = value;
                }
            }
        }

        /// <summary>
        /// Defines the maximum length before a word gets wrapped.
        /// </summary>
        public int MaxWordLength
        {
            get { return this.maxWordLength; }
            set
            {
                if (value <= 0)
                    throw new ArgumentOutOfRangeException("value");
                if (this.maxWordLength != value)
                {
                    this.maxWordLength = value;
                }
            }
        }

        /// <summary>
        /// Defines the format of the date and time displayed for each chat message.
        /// </summary>
        public string DateFormat
        {
            get { return this.dateFormat; }
            set
            {
                value = value ?? "";
                if (!this.dateFormat.Equals(value))
                {
                    this.dateFormat = value;
                }
            }
        }

        /// <summary>
        /// Defines if font colors persist without the need to assign them to each message.
        /// </summary>
        public bool PersistFontColor
        {
            get { return this.persistFontColor; }
            set
            {
                if (this.persistFontColor != value)
                {
                    this.persistFontColor = value;
                }
            }
        }

        /// <summary>
        /// The default font color. Uses the page default font color if set to null.
        /// </summary>
        public string FontColor
        {
            get { return this.fontColor; }
            set
            {
                if (this.fontColor != value)
                {
                    this.fontColor = value;
                }
            }
        }

        /// <summary>
        /// Defines if sounds are played.
        /// </summary>
        public bool Audio
        {
            get { return this.audio; }
            set
            {
                if (this.audio != value)
                {
                    this.audio = value;
                }
            }
        }

        /// <summary>
        /// Defines the sound volume (0.0 = mute, 1.0 = max).
        /// </summary>
        public float AudioVolume
        {
            get { return this.audioVolume; }
            set
            {
                if (value < 0.0f) value = 0.0f;
                if (value > 1.0f) value = 1.0f;
                if (this.audioVolume != value)
                {
                    this.audioVolume = value;
                }
            }
        }

        /// <summary>
        /// Defines the sound that is played when normal messages are received.
        /// </summary>
        public string SoundReceive
        {
            get { return this.soundReceive; }
            set
            {
                if (this.soundReceive != value)
                {
                    this.soundReceive = value;
                }
            }
        }

        /// <summary>
        /// Defines the sound that is played on sending normal messages.
        /// </summary>
        public string SoundSend
        {
            get { return this.soundSend; }
            set
            {
                if (this.soundSend != value)
                {
                    this.soundSend = value;
                }
            }
        }

        /// <summary>
        /// Defines the sound that is played on channel enter or login.
        /// </summary>
        public string SoundEnter
        {
            get { return this.soundEnter; }
            set
            {
                if (this.soundEnter != value)
                {
                    this.soundEnter = value;
                }
            }
        }

        /// <summary>
        /// Defines the sound that is played on channel leave or logout.
        /// </summary>
        public string SoundLeave
        {
            get { return this.soundLeave; }
            set
            {
                if (this.soundLeave != value)
                {
                    this.soundLeave = value;
                }
            }
        }

        /// <summary>
        /// Defines the sound that is played on chatBot messages.
        /// </summary>
        public string SoundChatBot
        {
            get { return this.soundChatBot; }
            set
            {
                if (this.soundChatBot != value)
                {
                    this.soundChatBot = value;
                }
            }
        }

        /// <summary>
        /// Defines the sound that is played on error messages.
        /// </summary>
        public string SoundError
        {
            get { return this.soundError; }
            set
            {
                if (this.soundError != value)
                {
                    this.soundError = value;
                }
            }
        }

        /// <summary>
        /// Defines if the document title blinks on new messages.
        /// </summary>
        public bool Blink
        {
            get { return this.blink; }
            set
            {
                if (this.blink != value)
                {
                    this.blink = value;
                }
            }
        }

        /// <summary>
        /// Defines the blink interval in milliseconds.
        /// </summary>
        public int BlinkInterval
        {
            get { return this.blinkInterval; }
            set
            {
                if (value <= 0)
                    throw new ArgumentOutOfRangeException("value");
                if (this.blinkInterval != value)
                {
                    this.blinkInterval = value;
                }
            }
        }

        /// <summary>
        /// Defines the number of blink intervals
        /// </summary>
        public int BlinkIntervalNumber
        {
            get { return this.blinkIntervalNumber; }
            set
            {
                if (value <= 0)
                    throw new ArgumentOutOfRangeException("value");
                if (this.blinkIntervalNumber != value)
                {
                    this.blinkIntervalNumber = value;
                }
            }
        }

        public string IgnoredUserNames
        {
            get { return this.ignoredUserNames; }
            set
            {
                value = value ?? "";
                if (!this.ignoredUserNames.Equals(value))
                {
                    this.ignoredUserNames = value;
                }
            }
        }

        private static string[] sSettingNames;

        public static string[] GetSettingNames()
        {
            if (sSettingNames == null)
            {
                try
                {
                    System.Reflection.PropertyInfo[] props = typeof(AjaxChatSettings).GetProperties(
                        System.Reflection.BindingFlags.Public |
                        System.Reflection.BindingFlags.GetProperty |
                        System.Reflection.BindingFlags.SetProperty);
                    string[] names = new string[props.Length];
                    for (int i = props.Length - 1; i >= 0; i--)
                    {
                        names[i] = props[i].Name;
                    }
                    sSettingNames = names;
                }
                catch (Exception)
                {
                }
            }
            return sSettingNames;
        }

        public object GetSetting(string name)
        {
            try
            {
                System.Reflection.PropertyInfo prop = typeof(AjaxChatSettings).GetProperty(name,
                    System.Reflection.BindingFlags.IgnoreCase |
                    System.Reflection.BindingFlags.Public |
                    System.Reflection.BindingFlags.GetProperty |
                    System.Reflection.BindingFlags.SetProperty);
                if (prop == null) return null;
                return prop.GetValue(this, null);
            }
            catch (Exception)
            {
                return null;
            }
        }

        public bool SetSetting(string name, object value)
        {
            try
            {
                System.Reflection.PropertyInfo prop = typeof(AjaxChatSettings).GetProperty(name,
                    System.Reflection.BindingFlags.IgnoreCase |
                    System.Reflection.BindingFlags.Public |
                    System.Reflection.BindingFlags.GetProperty |
                    System.Reflection.BindingFlags.SetProperty);
                if (prop == null)
                {
                    return false;
                }
                else
                {
                    prop.SetValue(this, value, null);
                    return true;
                }
            }
            catch (Exception)
            {
                return false;
            }
        }

        /*public object this[string key]
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }/* */
    }
}
